/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0.
 * See `LICENSE` in the project root for license information.
 */

package me.ijleex.jmh.benchmark.counter.impl;

import java.util.concurrent.locks.StampedLock;

import me.ijleex.jmh.benchmark.counter.Counter;

/**
 * StampedOptimisticCounter.
 *
 * @author liym
 * @since 2020-05-27 13:15 新建
 */
public class StampedOptimisticCounter implements Counter {

    private final StampedLock lock = new StampedLock();

    private long counter;

    @Override
    public void increment() {
        long stamp = this.lock.writeLock();
        try {
            ++this.counter;
        } finally {
            this.lock.unlockWrite(stamp);
        }
    }

    @Override
    public long getCount() {
        long stamp = this.lock.tryOptimisticRead();
        long count;
        if (this.lock.validate(stamp)) {
            count = this.counter;
        } else {
            stamp = this.lock.readLock();
            try {
                count = this.counter;
            } finally {
                this.lock.unlockRead(stamp);
            }
        }
        return count;
    }

}
